/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.pentaho.di.ui.repository.dialog;

import cn.hutool.core.lang.Console;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.*;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.EngineMetaInterface;
import org.pentaho.di.core.LastUsedFile;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleJobException;
import org.pentaho.di.core.exception.KettleTransException;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.repository.*;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.ui.core.ConstUI;
import org.pentaho.di.ui.core.PropsUI;
import org.pentaho.di.ui.core.dialog.ErrorDialog;
import org.pentaho.di.ui.core.gui.GUIResource;
import org.pentaho.di.ui.core.gui.WindowProperty;
import org.pentaho.di.ui.repository.RepositoryDirectoryUI;
import org.pentaho.di.ui.spoon.Spoon;
import org.pentaho.di.ui.trans.step.BaseStepDialog;
import org.pentaho.ui.xul.components.XulMessageBox;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;

/**
 * Allows the user to make a selection of an Object in the repository
 *
 * @author tanpeng@yzbdl.ac.cn
 * @since 06-08-2021
 */
public class SaveObjectDialog extends Dialog {
  private static Class<?> PKG = RepositoryDialogInterface.class; // for
  // i18n
  // purposes,
  // needed
  // by
  // Translator2!!

  private Supplier<Spoon> spoonSupplier = Spoon::getInstance;

  protected XulMessageBox messageBox;


  private Label wlTree,wlFileName;
  private Tree wTree;
  private FormData fdlTree, fdTree, fdexpandAll,ffileName,fdlFileName;

  private Button wOK, wCancel;
  private Listener lsOK, lsCancel;

  private Shell shell;
  private SelectionAdapter lsDef;

  private String shellText;
  private String lineText,wlFileNameText;
  private PropsUI props;

  private Color dircolor;
  private Repository rep;

  private String objectName;
  private RepositoryDirectoryInterface objectDirectory;
  private TreeColumn nameColumn;
  private TreeColumn userColumn;
  private TreeColumn changedColumn;
  private int sortColumn;
  private boolean ascending;
  private TreeColumn typeColumn;
  private RepositoryObjectType objectType;
  private boolean showTrans;
  private boolean showJobs;
  private TreeColumn descriptionColumn;

  private ToolItem expandAll, collapseAll, delObject;

  private String filterString = null;
  private Pattern pattern = null;

  private RepositoryDirectoryInterface directoryTree;

  private boolean includeDeleted,isOverWrite;

  private Text fileName = null;

  private ToolItem createFolder;

  private RepositoryElementMetaInterface repositoryObject;

  private ObjectId objectId;

  private String newName = null;

  public SaveObjectDialog(Shell parent, Repository rep ) {
    this( parent, rep, true, true );
  }

  public SaveObjectDialog(Shell parent, Repository rep, boolean showTransformations, boolean showJobs ) {
    super( parent, SWT.NONE );

    this.props = PropsUI.getInstance();
    this.rep = rep;
    this.showTrans = showTransformations;
    this.showJobs = showJobs;

    // TODO: make this a configuration option in the dialog!
    //
    this.includeDeleted = false;

    shellText = BaseMessages.getString( PKG, "SaveObjectDialog.Dialog.Main.Title" );
    lineText = BaseMessages.getString( PKG, "SaveObjectDialog.Dialog.Object.Title" );
    wlFileNameText = BaseMessages.getString( PKG, "SaveObjectDialog.Dialog.Object.FileName" );
    objectName = null;
    objectDirectory = null;

    sortColumn = 0;
    ascending = false;

  }

  @SuppressWarnings( "deprecation" )
  public String open() {
    Shell parent = getParent();
    dircolor = GUIResource.getInstance().getColorDirectory();

    shell =
        new Shell( parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.SHEET | SWT.RESIZE | SWT.MIN | SWT.MAX );
    props.setLook( shell );
    shell.setImage( GUIResource.getInstance().getImageSpoon() );

    FormLayout formLayout = new FormLayout();
    formLayout.marginWidth = Const.FORM_MARGIN;
    formLayout.marginHeight = Const.FORM_MARGIN;

    shell.setLayout( formLayout );
    shell.setText( shellText );

    int margin = Const.MARGIN;

    ToolBar treeTb = new ToolBar( shell, SWT.HORIZONTAL | SWT.FLAT );
    props.setLook( treeTb );

    createFolder = new ToolItem( treeTb, SWT.PUSH );
    createFolder.setImage( GUIResource.getInstance().getAddFolderImage() );
    createFolder.setToolTipText( BaseMessages.getString( PKG, "SaveObjectDialog.Folder.Add" ) );

    delObject = new ToolItem( treeTb, SWT.PUSH );
    delObject.setImage( GUIResource.getInstance().getImageDelete() );
    delObject.setToolTipText( BaseMessages.getString( PKG, "SaveObjectDialog.Object.Delete" ) );

    expandAll = new ToolItem( treeTb, SWT.PUSH );
    expandAll.setImage( GUIResource.getInstance().getImageExpandAll() );

    collapseAll = new ToolItem( treeTb, SWT.PUSH );
    collapseAll.setImage( GUIResource.getInstance().getImageCollapseAll() );

    fdexpandAll = new FormData();
    fdexpandAll.right = new FormAttachment( 100, -margin );
    fdexpandAll.top = new FormAttachment( 0, margin );
    treeTb.setLayoutData( fdexpandAll );

    // From step line
    wlTree = new Label( shell, SWT.NONE );
    wlTree.setText( lineText );
    props.setLook( wlTree );
    fdlTree = new FormData();
    fdlTree.left = new FormAttachment( 0, 0 );
    fdlTree.top = new FormAttachment( 0, margin );
    fdlTree.width = 640;
    wlTree.setLayoutData( fdlTree );

    wTree = new Tree( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL );
    wTree.setHeaderVisible( true );
    props.setLook( wTree );


    // Add some columns to it as well...
    nameColumn = new TreeColumn( wTree, SWT.LEFT );
    nameColumn.setText( BaseMessages.getString( PKG, "RepositoryExplorerDialog.Column.Name" ) );
    nameColumn.setWidth( 350 );
    nameColumn.addListener( SWT.Selection, new Listener() {
      public void handleEvent( Event e ) {
        setSort( 0 );
      }
    } );

    // No sorting on the type column just yet.
    typeColumn = new TreeColumn( wTree, SWT.LEFT );
    typeColumn.setText( BaseMessages.getString( PKG, "RepositoryExplorerDialog.Column.Type" ) );
    typeColumn.setWidth( 100 );
    typeColumn.addListener( SWT.Selection, new Listener() {
      public void handleEvent( Event e ) {
        setSort( 1 );
      }
    } );

    userColumn = new TreeColumn( wTree, SWT.LEFT );
    userColumn.setText( BaseMessages.getString( PKG, "RepositoryExplorerDialog.Column.User" ) );
    userColumn.setWidth( 100 );
    userColumn.addListener( SWT.Selection, new Listener() {
      public void handleEvent( Event e ) {
        setSort( 2 );
      }
    } );

    changedColumn = new TreeColumn( wTree, SWT.LEFT );
    changedColumn.setText( BaseMessages.getString( PKG, "RepositoryExplorerDialog.Column.Changed" ) );
    changedColumn.setWidth( 120 );
    changedColumn.addListener( SWT.Selection, new Listener() {
      public void handleEvent( Event e ) {
        setSort( 3 );
      }
    } );

    descriptionColumn = new TreeColumn( wTree, SWT.LEFT );
    descriptionColumn.setText( BaseMessages.getString( PKG, "RepositoryExplorerDialog.Column.Description" ) );
    descriptionColumn.setWidth( 120 );
    descriptionColumn.addListener( SWT.Selection, new Listener() {
      public void handleEvent( Event e ) {
        setSort( 4 );
      }
    } );

    props.setLook( wTree );
    fdTree = new FormData();
    fdTree.left = new FormAttachment( 0, 0 );
    fdTree.right = new FormAttachment( 100, 0 );
    fdTree.top = new FormAttachment( treeTb, margin );
    fdTree.bottom = new FormAttachment( 100, -110 );
    fdTree.height = 800;
    wTree.setLayoutData( fdTree );

    // 存储到资源库的文件名 标题
    wlFileName = new Label( shell, SWT.NONE );
    wlFileName.setText( wlFileNameText );
    props.setLook( wlFileName );
    fdlFileName = new FormData();
    fdlFileName.left = new FormAttachment( 0, 0 );
    fdlFileName.top = new FormAttachment( wTree, 2*margin );
    wlFileName.setLayoutData( fdlFileName );

    // 存储到资源库的文件名
    fileName = new Text( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER );
    fileName.setToolTipText( BaseMessages.getString( PKG, "SaveObjectDialog.Save.FileName.ToolTip" ) );
    props.setLook( fileName );
    ffileName = new FormData();
    ffileName.left = new FormAttachment(0, 0);
    ffileName.right = new FormAttachment( 100, 0 );
    ffileName.top = new FormAttachment( wlFileName, margin );
    fileName.setLayoutData( ffileName );

    // Some buttons
    wOK = new Button( shell, SWT.PUSH );
    wOK.setText( BaseMessages.getString( PKG, "System.Button.OK" ) );
    lsOK = new Listener() {
      public void handleEvent( Event e ) {
        ok();
      }
    };
    wOK.addListener( SWT.Selection, lsOK );
    wOK.setEnabled( false );

    wCancel = new Button( shell, SWT.PUSH );
    wCancel.setText( BaseMessages.getString( PKG, "System.Button.Cancel" ) );
    lsCancel = new Listener() {
      public void handleEvent( Event e ) {
        cancel();
      }
    };
    wCancel.addListener( SWT.Selection, lsCancel );

    BaseStepDialog.positionBottomButtons( shell, new Button[] { wOK, wCancel }, margin, null );
    // Add listeners

    lsDef = new SelectionAdapter() {
      public void widgetDefaultSelected( SelectionEvent e ) {
        if(Boolean.TRUE.equals( wTree.getSelection()[ 0 ].getData( "isFolder" ) )){
          createFolder(wTree.getSelection());
        }
      }
    };
    wTree.addSelectionListener( lsDef );

    wTree.addKeyListener( new KeyAdapter() {
      public void keyPressed( KeyEvent e ) {
        if ( e.character == SWT.CR ) {
          ok();
        }
      }
    } );

    fileName.addKeyListener( new KeyAdapter() {
      public void keyReleased(KeyEvent keyEvent) {
        // 控制确认按钮
        if ( StringUtils.isNotBlank(fileName.getText()) ) {
          wOK.setEnabled(true);
        }else{
          wOK.setEnabled(false);
        }
//        // 这里键盘抬起事件可以用来给指定对象赋值
//        objectName = fileName.getText();
      }
    } );

    wTree.addSelectionListener( new SelectionAdapter() {
      public void widgetSelected( SelectionEvent e ) {
        if ( wTree.getSelection().length > 0 ) {
          wOK.setEnabled( Boolean.TRUE.equals( StringUtils.isNotBlank(fileName.getText())) );
          createFolder.setEnabled( Boolean.TRUE.equals( wTree.getSelection()[ 0 ].getData( "isFolder" ) ) );
          updateSavePath(wTree.getSelection());
        }
      }
    } );

    createFolder.addSelectionListener( new SelectionAdapter() {
      public void widgetSelected( SelectionEvent event ) {
        createFolder( wTree.getSelection() );
      }
    } );

    expandAll.addSelectionListener( new SelectionAdapter() {
      public void widgetSelected( SelectionEvent event ) {
        expandAllItems( wTree.getItems(), true );
      }
    } );

    collapseAll.addSelectionListener( new SelectionAdapter() {
      public void widgetSelected( SelectionEvent event ) {
        expandAllItems( wTree.getItems(), false );
      }
    } );

    delObject.addSelectionListener( new SelectionAdapter() {
      public void widgetSelected( SelectionEvent event ) {
        deleteObject(wTree.getSelection());
      }
    } );

    shell.addShellListener( new ShellAdapter() {
      public void shellClosed( ShellEvent e ) {
        cancel();
      }
    } );

    try {

      if ( rep instanceof RepositoryExtended ) {
        RepositoryExtended repositoryExtended = (RepositoryExtended) this.rep;
        directoryTree = repositoryExtended.loadRepositoryDirectoryTree( "/", "*.kjb|*.ktr", -1, BooleanUtils.isTrue( repositoryExtended.getUserInfo().isAdmin() ), true, false );
      } else {
        directoryTree = this.rep.loadRepositoryDirectoryTree();
      }

    } catch ( KettleException e ) {
      new ErrorDialog( shell,
          BaseMessages.getString( PKG, "SelectObjectDialog.Dialog.ErrorRefreshingDirectoryTree.Title" ),
          BaseMessages.getString( PKG, "SelectObjectDialog.Dialog.ErrorRefreshingDirectoryTree.Message" ), e );
    } // catch()

    getData();
    wTree.setFocus();
    BaseStepDialog.setSize( shell );

    shell.open();
    while ( !shell.isDisposed() ) {
      if ( !shell.getDisplay().readAndDispatch() ) {
        shell.getDisplay().sleep();
      }
    }
    return objectName;
  }

  /**
   * 展开全部
   * @param treeitems
   * @param expand
   */
  private void expandAllItems( TreeItem[] treeitems, boolean expand ) {
    for ( TreeItem item : treeitems ) {
      item.setExpanded( expand );
      if ( item.getItemCount() > 0 ) {
        expandAllItems( item.getItems(), expand );
      }
    }
  }

  /**
   * 创建目录
   * @param treeitems
   */
  private void createFolder( TreeItem[] treeitems ) {
      try {

        if ( treeitems == null || treeitems.length == 0 ) {
          return;
        }
        TreeItem selectedFolder = treeitems[0];

        CreateFolderDialog sdd = new CreateFolderDialog(shell, new CreateFolderCallback() {
          @Override
          public void ok(String folderName) {
            newName = folderName;
          }

          @Override
          public void cancel() {
            newName = null;
            createFolder.setEnabled(false);
          }
        });
        sdd.open();

        if ( newName != null ) {
          //Do an explicit check here to see if the folder already exists in the ui
          //This is to prevent a double message being sent in case the folder does
          //not exist in the ui but does exist in the repo (PDI-5202)
          boolean folderExistsInUI = selectedFolder.getText().equals( newName );
          if ( folderExistsInUI ) {
            throw new Exception(
                    BaseMessages.getString(
                            PKG,
                            "BrowserController.DirAlreadyExistsInUI",
                            newName
                    )
            );
          }

          Object selectObj = selectedFolder.getData();
          if(selectObj instanceof RepositoryDirectoryInterface){
            objectDirectory = (RepositoryDirectoryInterface) selectObj;
            objectId = objectDirectory.getObjectId();
            objectName = objectDirectory.getName();
          }
//          else{
//            repositoryObject = (RepositoryElementMetaInterface) selectObj;
//            if ( repositoryObject != null ) {
//              objectName = repositoryObject.getName();
//              objectDirectory = repositoryObject.getRepositoryDirectory();
//              objectId = repositoryObject.getObjectId();
//              objectType = repositoryObject.getObjectType();
//            } else {
//              // For backward compatibility, we should rarely end up here...
//              //
//              String[] path = ConstUI.getTreeStrings( selectedFolder.getParentItem() );
//              objectName = selectedFolder.getText( 0 );
//              objectType = null;
//              for ( RepositoryObjectType type : RepositoryObjectType.values() ) {
//                if ( type.getTypeDescription().equalsIgnoreCase( selectedFolder.getText( 1 ) ) ) {
//                  objectType = type;
//                  break;
//                }
//              }
//              objectDirectory = directoryTree.findDirectory( path );
//            }
//          }

          //PDI-5202
          String newNameInRepo = checkDirNameExistsInRepo( newName );
          if ( newNameInRepo != null ) {
            messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Warning" ) );
            messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) );
            messageBox.setMessage(
                    BaseMessages.getString(
                            PKG,
                            "BrowserController.DirAlreadyExistsInRepository",
                            newNameInRepo
                    )
            );
            messageBox.open();
            newName = newNameInRepo;
          }

          rep.createRepositoryDirectory( objectDirectory, newName );

        }
        newName = null;
        refreshTree();
      } catch ( Exception e ) {
          messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Error" ) );
          messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) );
          messageBox.setMessage( BaseMessages.getString( PKG, e.getLocalizedMessage() ) );
          messageBox.open();
        }
  }

  /**
   * 检查是否有重名文件
   * @param name
   * @return
   * @throws KettleException
   */
  public String checkDirNameExistsInRepo( String name ) throws KettleException {
    String[] dirNames = rep.getDirectoryNames( getObjectId() );
    for ( String dirName : dirNames ) {
      if ( dirName.equalsIgnoreCase( name ) ) {
        return dirName;
      }
    }
    return null;
  }

  /**
   * 更新当前转换存储名称
   * @param treeitems
   */
  public void updateSavePath( TreeItem[] treeitems ) {
    if ( treeitems == null || treeitems.length == 0 ) {
      return;
    }
    TreeItem pathFolder = treeitems[0];
    if(Boolean.TRUE.equals( pathFolder.getData("isFolder"))){
      objectDirectory = (RepositoryDirectoryInterface) pathFolder.getData();
    }else{
      // 控制确认按钮可用性
      if ( StringUtils.isNotBlank(fileName.getText()) ) {
        wOK.setEnabled(true);
      }else{
        wOK.setEnabled(false);
      }
      RepositoryElementMetaInterface selectObj = (RepositoryElementMetaInterface) pathFolder.getData();
      fileName.setText(selectObj.getName());
      objectDirectory = selectObj.getRepositoryDirectory();
      if(!objectDirectory.isRoot()){
        objectDirectory = objectDirectory.getParent();
      }
    }
    wlTree.setText( lineText+":  "+objectDirectory.getPath() );

  }

  /**
   * 删除对象
   * @param treeitems
   */
  private void deleteObject( TreeItem[] treeitems ) {
    if ( treeitems == null || treeitems.length == 0 ) {
      return;
    }
    TreeItem pathFolder = treeitems[0];
    Object selectObj = pathFolder.getData();
    try {
      if(selectObj instanceof RepositoryDirectoryInterface){ //删除目录
        objectDirectory = (RepositoryDirectoryInterface) selectObj;
        objectId = objectDirectory.getObjectId();
        objectName = objectDirectory.getName();

        // 校验是否存在打开的转换
        isFileOpenedInFolder( objectDirectory.getPath());
        // 删除使用记录
        removeRecentsUsingPath(objectDirectory.getPath());
        // 删除目录
        rep.deleteRepositoryDirectory(objectDirectory);
      }else{ // 删除单个对象
        repositoryObject = (RepositoryElementMetaInterface) selectObj;
        if(null != repositoryObject){
          objectType = repositoryObject.getObjectType();
          objectName = repositoryObject.getName();
          objectDirectory = repositoryObject.getRepositoryDirectory();
          objectId = repositoryObject.getObjectId();
        }else{
          // 什么都没做，无法向后兼容
  //        String[] path = ConstUI.getTreeStrings( pathFolder.getParentItem() );
  //        objectName = pathFolder.getText( 0 );
  //        objectType = null;
  //        for ( RepositoryObjectType type : RepositoryObjectType.values() ) {
  //          if ( type.getTypeDescription().equalsIgnoreCase( pathFolder.getText( 1 ) ) ) {
  //            objectType = type;
  //            break;
  //          }
  //        }
  //        objectDirectory = directoryTree.findDirectory( path );
          return;
        }
        switch (objectType.toString()){
          case "job":
            if ( isJobOpened( objectId.getId(), objectDirectory.getPath(), objectName ) ) {
              throw new KettleJobException();
            }
            removeRecent( objectId.getId(), objectType.toString() );
            rep.deleteJob( () -> objectId.getId() );
            break;
          case "transformation":
            if ( isTransOpened( objectId.getId(), objectDirectory.getPath(), objectName ) ) {
              throw new KettleTransException();
            }
            removeRecent( objectId.getId(), objectType.toString() );
            rep.deleteTransformation( () -> objectId.getId() );
            break;
        }
      }
      refreshTree();
    } catch ( KettleException e ) {
      new ErrorDialog( shell,
              BaseMessages.getString( PKG, "RepositoryExplorerDialog.Directory.Delete.ErrorRemoving.Title" ),
              BaseMessages.getString( PKG, "RepositoryExplorerDialog.Directory.Delete.ErrorRemoving.Message1" ), e );
    }
  }

  /**
   * 当前目录是否打开了转换
   * @param path
   * @throws KettleException
   */
  private void isFileOpenedInFolder( String path ) throws KettleException {
    List<TransMeta> openedTransFiles = getSpoon().delegates.trans.getTransformationList();
    for ( TransMeta t : openedTransFiles ) {
      if ( t.getRepositoryDirectory().getPath() != null
              && ( t.getRepositoryDirectory().getPath() + "/" ).startsWith( path + "/" ) ) {
        throw new KettleTransException();
      }
    }
    List<JobMeta> openedJobFiles = getSpoon().delegates.jobs.getJobList();
    for ( JobMeta j : openedJobFiles ) {
      if ( j.getRepositoryDirectory().getPath() != null
              && ( j.getRepositoryDirectory().getPath() + "/" ).startsWith( path + "/" ) ) {
        throw new KettleJobException();
      }
    }
  }

  /**
   * 从最近使用中移除
   * @param path
   */
  private void removeRecentsUsingPath( String path ) {
    Collection<List<LastUsedFile>> lastUsedRepoFiles = PropsUI.getInstance().getLastUsedRepoFiles().values();
    for ( List<LastUsedFile> lastUsedFiles : lastUsedRepoFiles ) {
      for ( int i = 0; i < lastUsedFiles.size(); i++ ) {
        if ( ( lastUsedFiles.get( i ).getDirectory() + "/" ).startsWith( path + "/" ) ) {
          lastUsedFiles.remove( i );
          i--;
        }
      }
    }
  }

  /**
   * 删除对象
   * @param id
   * @param type
   * @return
   */
  private boolean removeRecent( String id, String type ) {
    RepositoryObject repositoryObject = null;
    try {
      repositoryObject = rep.getObjectInformation( () -> id,
              ( type == "transformation" ? RepositoryObjectType.TRANSFORMATION : RepositoryObjectType.JOB ) );
    } catch ( Exception e ) {
      return false;
    }

    if ( repositoryObject != null ) {
      Collection<List<LastUsedFile>> lastUsedRepoFiles = PropsUI.getInstance().getLastUsedRepoFiles().values();
      for ( List<LastUsedFile> lastUsedFiles : lastUsedRepoFiles ) {
        for ( LastUsedFile lastUsedFile : lastUsedFiles ) {
          if ( lastUsedFile.getDirectory().equals( repositoryObject.getRepositoryDirectory().getPath() ) && lastUsedFile
                  .getFilename().equals( repositoryObject.getName() ) ) {
            lastUsedFiles.remove( lastUsedFile );
            return true;
          }
        }
      }
    }
    return true;
  }

  /**
   * 该转换是否打开
   * @param id
   * @param path
   * @param name
   * @return
   */
  private boolean isTransOpened( String id, String path, String name ) {
    List<TransMeta> openedTransFiles = getSpoon().delegates.trans.getTransformationList();
    for ( TransMeta t : openedTransFiles ) {
      if ( t.getObjectId() != null && id.equals( t.getObjectId().getId() )
              || ( path.equals( t.getRepositoryDirectory().getPath() ) && name.equals( t.getName() ) ) ) {
        return true;
      }
    }
    return false;
  }

  /**
   * 该作业是否打开
   * @param id
   * @param path
   * @param name
   * @return
   */
  private boolean isJobOpened( String id, String path, String name ) {
    List<JobMeta> openedJobFiles = getSpoon().delegates.jobs.getJobList();
    for ( JobMeta j : openedJobFiles ) {
      if ( j.getObjectId() != null && id.equals( j.getObjectId().getId() )
              || ( path.equals( j.getRepositoryDirectory().getPath() ) && name.equals( j.getName() ) ) ) {
        return true;
      }
    }
    return false;
  }

  /**
   * 获取Spoon对象
   * @return
   */
  protected Spoon getSpoon() {
    return spoonSupplier.get();
  }

  protected void setSort( int i ) {
    if ( sortColumn == i ) {
      ascending = !ascending;
    } else {
      sortColumn = i;
      ascending = true;
    }

    if ( sortColumn >= 0 && sortColumn < 5 ) {
      TreeColumn column = wTree.getColumn( sortColumn );
      wTree.setSortColumn( column );
      wTree.setSortDirection( ascending ? SWT.UP : SWT.DOWN );
    }
    refreshTree();
  }

  private void refreshTree() {
    try {
      wTree.removeAll();
      TreeItem ti = null;
      // If the directory is a root directory and is visible to the user we will
      // display that on the UI otherwise we will hide it
      if ( directoryTree.isRoot() && directoryTree.isVisible() ) {
        ti = new TreeItem( wTree, SWT.NONE );
        ti.setImage( GUIResource.getInstance().getImageFolder() );
        ti.setExpanded( true );
        RepositoryDirectoryUI.getTreeWithNames(
            ti, rep, dircolor, sortColumn, includeDeleted, ascending, showTrans, showJobs, directoryTree,
            filterString, pattern );
      } else {
        for ( int i = 0; i < directoryTree.getNrSubdirectories(); i++ ) {
          RepositoryDirectory subdir = directoryTree.getSubdirectory( i );
          ti = new TreeItem( wTree, SWT.NONE );
          ti.setImage( GUIResource.getInstance().getImageFolder() );
          RepositoryDirectoryUI.getTreeWithNames(
              ti, rep, dircolor, sortColumn, includeDeleted, ascending, showTrans, showJobs, subdir, filterString,
              pattern );
        }
      }
    } catch ( KettleException e ) {
      new ErrorDialog(
          shell, BaseMessages.getString( PKG, "SelectObjectDialog.Dialog.UnexpectedError.Title" ), BaseMessages
          .getString( PKG, "SelectObjectDialog.Dialog.UnexpectedError.Message" ), e );
    }
  }

  public void dispose() {
    props.setScreen( new WindowProperty( shell ) );
    shell.dispose();
  }

  public void getData() {
    setSort( 0 );
  }

  private void cancel() {
    objectName = null;
    dispose();
  }

  private void ok() {
    if(StringUtils.isBlank(fileName.getText())){
      MessageBox messageDialog = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
      messageDialog.setText("警告");
      messageDialog.setMessage("文件名不能为空！");
      messageDialog.open();
      return;
    }
    try {
      // Something has to be selected!
      if ( wTree.getSelectionCount() > 0 ) {
        TreeItem ti = wTree.getSelection()[ 0 ];
        // No directory!
        if ( !Boolean.TRUE.equals( wTree.getSelection()[ 0 ].getData( "isFolder" ) ) ) {
          int level = ConstUI.getTreeLevel( ti );
          if ( level > 0 ) {
            repositoryObject = (RepositoryElementMetaInterface) ti.getData();
            if ( repositoryObject != null ) {
              // 应该直接取filename
              objectName = repositoryObject.getName().equals(fileName.getText())?repositoryObject.getName():fileName.getText();
              objectDirectory = repositoryObject.getRepositoryDirectory();
              if(!objectDirectory.isRoot()){
                objectDirectory = objectDirectory.getParent();
              }
              objectId = repositoryObject.getObjectId();
              objectType = repositoryObject.getObjectType();
            } else {
              // For backward compatibility, we should rarely end up here...
              //
              String[] path = ConstUI.getTreeStrings( ti.getParentItem() );
              objectName = ti.getText( 0 ).equals(fileName.getText())?ti.getText( 0 ):fileName.getText();
              objectType = null;
              for ( RepositoryObjectType type : RepositoryObjectType.values() ) {
                if ( type.getTypeDescription().equalsIgnoreCase( ti.getText( 1 ) ) ) {
                  objectType = type;
                  break;
                }
              }
              objectDirectory = directoryTree.findDirectory( path );
            }
          }
        }else {
          objectDirectory = (RepositoryDirectoryInterface) ti.getData();
          objectId = null;
          objectType = null;
          objectName = fileName.getText();
        }

          List<RepositoryElementMetaInterface> repositoryElementMetaInterfaces =
                  rep.getJobAndTransformationObjects( () -> objectDirectory.getObjectId().getId(), false );

          EngineMetaInterface meta = getSpoon().getActiveMeta();
          boolean exits = false;
          RepositoryElementMetaInterface exitsElement = null;
          for(RepositoryElementMetaInterface element:repositoryElementMetaInterfaces){
            if(element.getName().equals(fileName.getText())&&element.getObjectType().equals(meta.getRepositoryElementType())){
              exitsElement = element;
              exits = true;
              break;
            }
          }

          /**
           * 如果选中对象不等于输入对象 以输入对象为准
           */
          if(exits){
            MessageBox mb = new MessageBox( shell, SWT.OK | SWT.CANCEL |  SWT.ICON_WARNING );
            mb.setMessage( BaseMessages.getString( PKG, "SaveObjectDialog.Dialog.OverWrite.Message" ) );
            mb.setText( BaseMessages.getString( PKG, "SaveObjectDialog.Dialog.OverWrite.Title" ) );
            if (mb.open() == SWT.OK) {
              objectId = exitsElement.getObjectId();
              objectType = exitsElement.getObjectType();
            }else{
              return;
            }
          }else{
            objectId = null;
          }
      }
      if ( objectDirectory != null && StringUtils.isNotBlank(fileName.getText())) {
        dispose();
      } else {
        MessageBox mb = new MessageBox( shell, SWT.OK | SWT.ICON_ERROR );
        mb.setMessage( BaseMessages.getString( PKG, "SelectObjectDialog.Dialog.DirectoryNotFound.Message" ) );
        mb.setText( BaseMessages.getString( PKG, "SelectObjectDialog.Dialog.DirectoryNotFound.Title" ) );
        mb.open();
      }
    } catch (KettleException e) {
      Console.error(e);
      return;
    }
  }

  public RepositoryDirectoryInterface getDirectory() {
    return objectDirectory;
  }


  /**
   * @return the isOverWrite
   */
  public boolean isOverWrite() {
    return isOverWrite;
  }

  /**
   * @return the objectType
   */
  public RepositoryObjectType getObjectType() {
    return objectType;
  }

  /**
   * @return the objectName
   */
  public String getObjectName() {
    return objectName;
  }

  /**
   * @return the repositoryObject
   */
  public RepositoryElementMetaInterface getRepositoryObject() {
    return repositoryObject;
  }

  /**
   * @param repositoryObject the repositoryObject to set
   */
  public void setRepositoryObject( RepositoryElementMetaInterface repositoryObject ) {
    this.repositoryObject = repositoryObject;
  }

  /**
   * @return the objectId
   */
  public ObjectId getObjectId() {
    return objectId;
  }

  /**
   * @param objectId the objectId to set
   */
  public void setObjectId( ObjectId objectId ) {
    this.objectId = objectId;
  }
}
